package top.zywork.service;

import top.zywork.dos.DistributionUserDO;
import top.zywork.dos.MallCommissionGrantConfig;
import top.zywork.dto.PagerDTO;
import top.zywork.query.PageQuery;
import top.zywork.vo.ResponseStatusVO;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 分销数据查询Service接口<br/>
 *
 * 创建于2018-12-28<br/>
 *
 * @author 王振宇
 * @version 1.0
 */
public interface DistributionService {

    /**
     * 获取某个用户关系链中的顶级用户
     * @param userId
     * @return
     */
    DistributionUserDO getTheTop(Long userId);

    /**
     * 查询所有顶级分销商，及上面没有分销商
     * @return
     */
    PagerDTO listAllTop(Object queryObj);

    /**
     * 分页查询指定用户上面的几级经销商
     * @param userId 指定用户编号
     * @param distributionLevel 分销级别
     * @param levels 用户上面的几级经销商，如查询用户上面的一级经销商，则new Long[]{1}，如果查询用户上面的一级和二级经销商，则new Long[]{1, 2}
     * @param pageQuery 分页对象
     * @return
     */
    PagerDTO listAboveUsers(Long userId, Integer distributionLevel, Long[] levels, PageQuery pageQuery);

    /**
     * 分页查询指定用户的直接上级经销商
     * @param userId 指定用户编号
     * @param distributionLevel 分销级别
     * @param level 用户上面的几级经销商，如查询用户上面的二级经销商，则level = 2
     * @param pageQuery 分页对象
     * @return
     */
    PagerDTO listDirectAboveUsers(Long userId, Integer distributionLevel, Long level, PageQuery pageQuery);

    /**
     * 分页查询指定用户下面的几级经销商
     * @param userId 指定用户编号
     * @param levels 用户下面的几级经销商，如查询用户下面的二级经销商，则new Long[]{2}，如果查询用户上面的二级和三级经销商，则new Long[]{2, 3}
     * @param pageQuery 分页对象
     * @return
     */
    PagerDTO listBelowUsers(Long userId, Long[] levels, PageQuery pageQuery);

    /**
     * 分页查询指定用户的直接下级经销商
     * @param userId 指定用户编号
     * @param level 用户下面的几级经销商，如查询用户下面的二级经销商，level = 2
     * @param pageQuery 分页对象
     * @return
     */
    PagerDTO listDirectBelowUsers(Long userId, Long level, PageQuery pageQuery);

    /**
     * 对指定用户下的指定等级的分销商计数，需要返回总用户数，每一级的用户数
     * @param userId
     * @param levels
     * @return
     */
    List<Long> countBelowUsersPerLevel(Long userId, Long[] levels);

    /**
     * 指定用户的多个订单，给上级用户发放佣金，每一个订单发放一笔佣金
     * @param userId 用户编号（下单购买的用户）
     * @param orderIdAndNoAry 订单编号与订单号 {"id-orderNo", "id-orderNo"}
     * @param mallCommissionGrantConfig
     * @param pickupUserId 提货点用户编号
     */
    void grantCommission(Long userId, String[] orderIdAndNoAry, MallCommissionGrantConfig mallCommissionGrantConfig, Long pickupUserId);

    /**
     * 根据用户的订单去判断是否需要保存用户的分销商角色
     * @param userId
     * @param orderIds
     * @return
     */
    void saveDistributionUserRole(Long userId, Long[] orderIds);

    /**
     * 获取指定用户编号下级最大层级数
     * @param userId
     * @return
     */
    Integer getMaxLevel(Long userId);

    /**
     * 根据用户编号获取该用户所有下级总个数（团队计数）
     * @param userId
     * @return
     */
    Long countAllBelowUsers(Long userId);

    /**
     * 获取指定用户下的指定等级创造的商城订单总业绩
     * @param userId 用户编号
     * @param levels 分销等级，如new Long[]{2, 3, 4}
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    BigDecimal countMallBelowPerformance(Long userId, Long[] levels, Date beginTime, Date endTime);

    /**
     * 获取指定用户下的整个团队创造的商城订单总业绩
     * @param userId 用户编号
     * @param beginTime 开始时间
     * @param endTime 结束时间
     * @return
     */
    BigDecimal countMallAllBelowPerformance(Long userId, Date beginTime, Date endTime);

    /**
     * 把指定id的用户提升为顶级分销商，并且保留这个用户下的关系链
     * @param userId
     */
    ResponseStatusVO putToTop(Long userId);

    /**
     * 把指定id的用户提升到另外一个用户的直接下级，并且保留这个用户下的关系链
     * @param userId
     * @param toUserId
     */
    ResponseStatusVO putToUser(Long userId, Long toUserId);

}
